﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace WebSite.Controllers
{
    public class ChartSeries
    {
        public string Name { get; private set; }
        public Dictionary<string, double> Values { get; private set; }

        public ChartSeries(string name, Dictionary<string, double> values)
        {
            Name = name;
            Values = values;
        }
    }

    public static class ControllerChartHelperExtensions
    {
        private static readonly CultureInfo EnUsCultureInfo = new CultureInfo("en-US");

        public static MvcHtmlString GoogleBarChart(this HtmlHelper helper, string title, ChartSeries chartSeries, int width = 800, int height = 300)
        {
            string labels = String.Join("|", chartSeries.Values.Keys.Select(x => x.Replace(' ', '+')));
            string values = String.Join(",", chartSeries.Values.Values.Select(x => x.ToString("0.00", EnUsCultureInfo)));
            const double MinValue = 0;
            int maxValue = (int) Math.Ceiling(chartSeries.Values.Values.Max());

            string src = "http://chart.apis.google.com/chart" +
               "?chxl=0:|" + labels +
               "&chxr=1," + MinValue + "," + maxValue +
               "&chxs=0,676767,12.5,0,l,676767" +
               "&chxt=x,y" +
               "&chbh=a" +
               "&chs=" + width + "x" + height +
               "&cht=bvg" +
               "&chco=3399CC" +
               "&chds=" + MinValue + "," + maxValue +
               "&chd=t:" + values +
               "&chdl=" + chartSeries.Name.Replace(' ', '+').Replace("$", "%24") +
               "&chdlp=b" +
               "&chg=10,10,1,5" +
               "&chtt=" + title.Replace(' ', '+').Replace("$", "%24");

            TagBuilder tagBuilder = new TagBuilder("img");
            tagBuilder.Attributes["width"] = width.ToString();
            tagBuilder.Attributes["height"] = height.ToString();
            tagBuilder.Attributes["alt"] = title;
            tagBuilder.Attributes["src"] = src;

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.SelfClosing));
        }

        public static MvcHtmlString GooglePieChart(this HtmlHelper helper, string title, ChartSeries chartSeries, bool showTable = false, int maxValues = 7)
        {
            IEnumerable<KeyValuePair<string, double>> pieValues = chartSeries.Values.Where(x => x.Value != 0).OrderByDescending(x => x.Value);
            
            if (!pieValues.Any())
            {
                return MvcHtmlString.Create("Vazio");
            }

            double soma = pieValues.Sum(x => x.Value);
            string maxValue = pieValues.Max(x => x.Value).ToString("0.00", EnUsCultureInfo);

            int index = 1;
            StringBuilder labels = new StringBuilder();
            StringBuilder values = new StringBuilder();
            StringBuilder percentage = new StringBuilder();
            double somaTopFive = 0;
            foreach (KeyValuePair<string, double> pieValue in pieValues)
            {
                if (index != 1)
                {
                    labels.Append("|");
                    percentage.Append("|");
                    values.Append(",");
                }
                if (index > maxValues - 1 && pieValues.Count() > index)
                {
                    double outros = (soma - somaTopFive);
                    labels.Append("Outros R$ " + outros.ToString("#,##0.00", EnUsCultureInfo));
                    values.Append(outros.ToString("0.00", EnUsCultureInfo));
                    percentage.Append((outros*100/soma).ToString("0", EnUsCultureInfo));
                    break;
                }
                labels.Append(pieValue.Key + " R$ " + pieValue.Value.ToString("#,##0.00", EnUsCultureInfo));
                values.Append(pieValue.Value.ToString("0.00", EnUsCultureInfo));
                percentage.Append((pieValue.Value*100/soma).ToString("0", EnUsCultureInfo));
                somaTopFive += pieValue.Value;
                index++;
            }

            const int Width = 550;
            const int Height = 350;

            string src = "http://chart.apis.google.com/chart" +
                         "?chs=" + Width + "x" + Height +
                         "&cht=p" +
                         "&chds=0," + maxValue +
                         "&chl=" + percentage +
                         "&chd=t:" + values +
                         "&chdl=" + labels.ToString().Replace(' ', '+') +
                         "&chdlp=t" +
                         "&chco=FF0000,0000FF,00FF00,FF9900";

            if (!String.IsNullOrWhiteSpace(title))
            {
                src += "&chtt=" + title.Replace(' ', '+').Replace("$", "%24");
            }

            TagBuilder chartTagBuilder = new TagBuilder("img");
            chartTagBuilder.Attributes["width"] = Width.ToString();
            chartTagBuilder.Attributes["height"] = Height.ToString();
            chartTagBuilder.Attributes["alt"] = title;
            chartTagBuilder.Attributes["src"] = src;

            if (showTable)
            {
                StringBuilder rows = new StringBuilder();
                foreach (KeyValuePair<string, double> pieValue in pieValues)
                {
                    TagBuilder nameTagBuilder = new TagBuilder("td") {InnerHtml = pieValue.Key};
                    TagBuilder valueTagBuilder = new TagBuilder("td") { InnerHtml = "R$ " + pieValue.Value.ToString("#,##0.00") };
                    valueTagBuilder.Attributes["align"] = "right";
                    TagBuilder rowTagBuilder = new TagBuilder("tr") { InnerHtml = nameTagBuilder.ToString(TagRenderMode.Normal) + valueTagBuilder.ToString(TagRenderMode.Normal)};
                    rows.Append(rowTagBuilder.ToString(TagRenderMode.Normal));
                }
                TagBuilder tableTagBuilder = new TagBuilder("table") {InnerHtml = rows.ToString()};
                return MvcHtmlString.Create(chartTagBuilder.ToString(TagRenderMode.SelfClosing) + tableTagBuilder.ToString(TagRenderMode.Normal));
            }
            return MvcHtmlString.Create(chartTagBuilder.ToString(TagRenderMode.SelfClosing));
        }
    }
}